﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Licensed MIT: http://www.opensource.org/licenses/mit-license.php

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Management;

namespace DNA.Mvc.Management
{
    public class EntityRequestTraceWebEventProvider : EntityWebEventProvider
    {
        protected override void SaveToDB(System.Web.Management.WebBaseEventCollection events, int eventsDiscardedByBuffer, DateTime lastNotificationUtc)
        {
            try
            {
                using (var db = new LogDB(connectionName))
                {
                    WebRequestInformation requestInformation = null;
                    WebApplicationInformation applicationInformation = WebBaseEvent.ApplicationInformation;

                    foreach (WebBaseEvent e in events)
                    {
                        var _event = e as ExplicitilyWebRequestEvent;
                        if (_event != null)
                        {
                            requestInformation = ((WebRequestEvent)e).RequestInformation;
                            var request = _event.Request;

                            var requestEntry = new WebRequestEntry()
                            {
                                EventTime = e.EventTimeUtc,
                                UserHostAddress = _event.UserHostAddress, 
                                UserHostName = _event.UserHostName, 
                                UserAgent = request.UserAgent,
                                HttpMethod = request.HttpMethod,
                                IsAnonymous = !request.IsAuthenticated,
                                IsCrawler = request.Browser.Crawler,
                                Browser = request.Browser.Browser,
                                Version = request.Browser.Version
                            };

                            if (request.UrlReferrer != null)
                            {
                                if (!request.Url.Authority.Equals(request.UrlReferrer.Authority, StringComparison.OrdinalIgnoreCase))
                                    requestEntry.UrlRefer = request.UrlReferrer.ToString();
                            }

                            if ((request.RequestContext != null) && (request.RequestContext.RouteData != null) && (request.RequestContext.RouteData.Values != null))
                            {
                                var routeData = request.RequestContext.RouteData;

                                if (routeData.Values.ContainsKey("controller"))
                                    requestEntry.Controller = routeData.Values["controller"].ToString();

                                if (routeData.Values.ContainsKey("action"))
                                    requestEntry.Action = routeData.Values["action"].ToString();

                                if (routeData.Values.ContainsKey("website"))
                                    requestEntry.WebSiteName = routeData.Values["website"].ToString();

                                var _values = new Dictionary<string, object>();
                                foreach (var key in routeData.Values.Keys)
                                    _values.Add(key, routeData.Values[key]);
                                requestEntry.RouteValues = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(_values);
                            }

                            if (requestInformation != null)
                            {
                                requestEntry.RequestUrl = requestInformation.RequestUrl;
                                if ((requestInformation.Principal != null) && (requestInformation.Principal.Identity != null))
                                    requestEntry.UserName = requestInformation.Principal.Identity.Name;
                                else
                                    requestEntry.UserName = requestInformation.UserHostAddress;   
                            }
                            db.WebRequests.Add(requestEntry);
                        }
                    }
                    db.SaveChanges();
                }
            }
            catch(Exception ex)
            { 
            }
        }
    }
}
